package org.takeback.chat.lottery.listeners;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.takeback.chat.entity.GcLottery;
import org.takeback.chat.entity.Message;
import org.takeback.chat.lottery.Lottery;
import org.takeback.chat.lottery.LotteryDetail;
import org.takeback.chat.service.Game02Service;
import org.takeback.chat.store.room.LotteryFactory;
import org.takeback.chat.store.room.Room;
import org.takeback.chat.store.user.User;
import org.takeback.chat.utils.MessageUtils;
import org.takeback.chat.utils.NumberUtil;
import org.takeback.util.BeanUtils;

@Component("G02")
public class G02 extends DefaultGameListener {
	public static final String GET_MASTER_TEXT = "开始抢庄,谁大谁庄!";
	public static final String[] NAMES = { "牛牛", "牛①", "牛②", "牛③", "牛④", "牛⑤", "牛⑥", "牛⑦", "牛⑧", "牛⑨", "牛牛", "对子", "0对",
			"豹子" };
	@Autowired
	Game02Service game02Service;

	public void processStartEvent(Room room) throws GameException {
		super.processStartEvent(room);
		sendNewMasterRed(room);
		room.setStatus("1");
		this.lotteryService.setRoomStatus(room.getId(), "1");
	}

	public boolean onBeforeStart(Room room) throws GameException {
		return true;
	}

	public boolean onBeforeOpen(Integer uid, Lottery lottery) throws GameException {
		if ("1".equals(lottery.getType())) {
			return true;
		}
		if (uid.equals(lottery.getSender())) {
			return true;
		}
		Room room = (Room) this.roomStore.get(lottery.getRoomId());
		User user = (User) this.userStore.get(uid);
		if (lottery.getSender().equals(Integer.valueOf(0))) {
			Double money = Double.valueOf(getMasterDeposit(room));
			if (this.lotteryService.moneyDown(uid, money) < 1) {
				throw new GameException(500, "余额必须大于" + money + "元才能参与抢庄!");
			}
		} else {
			Double money = Double.valueOf(getDeposit(room));
			if (this.lotteryService.moneyDown(uid, money) < 1) {
				throw new GameException(500, "金额不能少于" + money + "元,请及时充值!");
			}
		}
		return true;
	}

	public void onOpen(Lottery lottery, LotteryDetail lotteryDetail) throws GameException {
		User opener = (User) this.userStore.get(lotteryDetail.getUid());
		Message notice = null;
		Room room = (Room) this.roomStore.get(lottery.getRoomId());
		if (lottery.getSender().equals(Integer.valueOf(0))) {
			Double money = Double.valueOf(getMasterDeposit(room));
			this.game02Service.saveDetail(lottery, lotteryDetail, money.doubleValue(), "G02");
			String msg = opener.getNickName() + " 一脸严肃,参与了抢庄";
			notice = new Message("TXT_SYS", Integer.valueOf(0), msg);
		} else {
			User sender = (User) this.userStore.get(lottery.getSender());
			Double money = Double.valueOf(getDeposit(room));
			if (lotteryDetail.getUid().equals(lottery.getSender())) {
				money = Double.valueOf(getMasterDeposit(room));
			}
			this.game02Service.saveDetail(lottery, lotteryDetail, money.doubleValue(), "G02");
			if (opener.getId().equals(lottery.getSender())) {
				return;
			}
			String msg = opener.getNickName() + " 抢走红包,与庄家兵戎相见!";
			notice = new Message("TXT_ALERT", Integer.valueOf(0), msg);
		}
		MessageUtils.broadcast((Room) this.roomStore.get(lottery.getRoomId()), notice);
	}

	public boolean onBeforeRed(LotteryFactory.DefaultLotteryBuilder builder) throws GameException {
		throw new GameException(500, "该房间不允许自由红包!");
	}

	public void onRed(LotteryFactory.DefaultLotteryBuilder builder) throws GameException {
	}

	public void onFinished(Lottery lottery) throws GameException {
		this.lotteryService.setLotteryFinished(lottery.getId());
		if (lottery.getSender().equals(Integer.valueOf(0))) {
			System.out.println(lottery.getId() + " finished");
			dealMaster(lottery);
			return;
		}
		dealGame(lottery);
	}

	public void processExpireEvent(Lottery lottery) throws GameException {
		super.processExpireEvent(lottery);
		this.lotteryService.setLotteryExpired(lottery.getId());
		if (lottery.getSender().equals(Integer.valueOf(0))) {
			System.out.println(lottery.getId() + " by " + lottery.getSender() + " expired");
			dealMaster(lottery);
			return;
		}
		dealGame(lottery);
	}

	private void dealGame(Lottery lottery) throws GameException {
		Room room = (Room) this.roomStore.get(lottery.getRoomId());
		Integer masterId = lottery.getSender();
		User master = (User) this.userStore.get(masterId);
		LotteryDetail masterDetail = (LotteryDetail) lottery.getDetail().get(masterId);
		int masterPoint = NumberUtil.getPoint(masterDetail.getCoin()).intValue();
		BigDecimal masterInout = new BigDecimal(0.0D);
		BigDecimal water = new BigDecimal(0.0D);
		Map<Integer, LotteryDetail> details = lottery.getDetail();
		StringBuilder msg = new StringBuilder("<table style='color:#0493b2'>");
		Map<Integer, Double> addMap = new HashMap();
		double feePercent = room.getFeeAdd() == null ? 0.0D : room.getFeeAdd().doubleValue();
		if ((feePercent >= 1.0D) || (feePercent < 0.0D)) {
			throw new RuntimeException("服务费设置错误!");
		}
		for (LotteryDetail ld : details.values()) {
			if (!ld.getUid().equals(masterId)) {
				User player = (User) this.userStore.get(ld.getUid());
				Integer playerPoint = NumberUtil.getPoint(ld.getCoin());

				msg.append("<tr><td>〖闲〗").append(player.getNickName()).append("(").append(ld.getCoin())
						.append(")</td>");
				if (masterPoint > playerPoint.intValue()) {
					BigDecimal inout = getInout(room, masterPoint);
					if (masterPoint == 10) {
						water = water.add(inout.multiply(new BigDecimal(feePercent)));
						masterInout = masterInout.add(inout.multiply(new BigDecimal(1.0D - feePercent)));
					} else {
						masterInout = masterInout.add(inout);
					}
					addMap.put(player.getId(), Double.valueOf(getDeposit(room) - inout.doubleValue()));
					msg.append("<td style='color:green;'>").append("牛").append(NAMES[playerPoint.intValue()])
							.append(" -").append(NumberUtil.format(inout)).append("</td>");
				} else if (masterPoint < playerPoint.intValue()) {
					BigDecimal inout = getInout(room, playerPoint.intValue());
					masterInout = masterInout.subtract(inout);
					if (playerPoint.intValue() == 10) {
						water = water.add(inout.multiply(new BigDecimal(feePercent)));
						inout = inout.multiply(new BigDecimal(1.0D - feePercent));
					}
					addMap.put(player.getId(), Double.valueOf(getDeposit(room) + inout.doubleValue()));
					msg.append("<td style='color:red;'>").append("牛").append(NAMES[playerPoint.intValue()]).append("+")
							.append(NumberUtil.format(inout)).append("</td>");
				} else if (masterDetail.getCoin().compareTo(ld.getCoin()) >= 0) {
					BigDecimal inout = getInout(room, masterPoint);
					if (masterPoint == 10) {
						water = water.add(inout.multiply(new BigDecimal(feePercent)));
						masterInout = masterInout.add(inout.multiply(new BigDecimal(1.0D - feePercent)));
					} else {
						masterInout = masterInout.add(inout);
					}
					addMap.put(player.getId(), Double.valueOf(getDeposit(room) - inout.doubleValue()));
					msg.append("<td style='color:green;'>").append(NAMES[playerPoint.intValue()]).append(" -")
							.append(NumberUtil.format(inout)).append("</td>");
				} else {
					BigDecimal inout = getInout(room, playerPoint.intValue());
					masterInout = masterInout.subtract(inout);
					if (playerPoint.intValue() == 10) {
						water = water.add(inout.multiply(new BigDecimal(feePercent)));
						inout = inout.multiply(new BigDecimal(1.0D - feePercent));
					}
					addMap.put(player.getId(), Double.valueOf(getDeposit(room) + inout.doubleValue()));
					msg.append("<td style='color:red;'>").append(NAMES[playerPoint.intValue()]).append("+")
							.append(NumberUtil.format(inout)).append("</td>");
				}
				msg.append("</tr>");
			}
		}
		msg.append("<tr><td  style='color:#B22222'>【庄】").append(master.getNickName()).append("(")
				.append(masterDetail.getCoin()).append(")</td>");
		if (masterInout.compareTo(new BigDecimal(0)) > 0) {
			msg.append("<td style='color:red'>").append(NAMES[masterPoint]).append("+")
					.append(NumberUtil.format(masterInout)).append("</td>");
		} else if (masterInout.compareTo(new BigDecimal(0)) < 0) {
			msg.append("<td style='color:green'>").append(NAMES[masterPoint]).append(" -")
					.append(NumberUtil.format(Math.abs(masterInout.doubleValue()))).append("</td></tr>");
		} else {
			msg.append("<td style='color:gray'>").append(NAMES[masterPoint]).append("\261平庄</td></tr>");
		}
		msg.append("</table>");

		masterInout = masterInout.add(new BigDecimal(getMasterDeposit(room)));

		addMap.put(masterId, Double.valueOf(masterInout.doubleValue()));
		this.game02Service.changeMoney(addMap, lottery, getDeposit(room), getMasterDeposit(room), water.doubleValue());
		Message rmsg = new Message("TXT_SYS", Integer.valueOf(0), msg.toString());
		MessageUtils.broadcast(room, rmsg);
		Integer masterTimes = room.getMasterTimes();
		room.setMasterTimes(masterTimes = Integer.valueOf(masterTimes.intValue() + 1));
		if (masterTimes.intValue() > 5) {
			sendNewMasterRed(room);
		} else {
			sendNewGameRed(master, room);
		}
	}

	private void dealMaster(Lottery lottery) throws GameException {
		Map<Integer, LotteryDetail> details = lottery.getDetail();
		Integer maxMan = Integer.valueOf(0);
		BigDecimal maxMoney = null;
		for (LotteryDetail ld : details.values()) {
			if ((maxMan.intValue() == 0) || (maxMoney.compareTo(ld.getCoin()) < 0)) {
				maxMan = ld.getUid();
				maxMoney = ld.getCoin();
			}
		}
		if (maxMan.equals(Integer.valueOf(0))) {
			String str = "<span style='color:#B22222'>无人参与抢庄,游戏结束.";
			Message msg = new Message("TXT_SYS", Integer.valueOf(0), str);
			Room room = (Room) this.roomStore.get(lottery.getRoomId());
			room.setStatus("0");
			this.game02Service.gameStop(lottery);
			MessageUtils.broadcast(room, msg);
			return;
		}
		User master = (User) this.userStore.get(maxMan);
		String str = "<span style='color:#B22222'>" + master.getNickName() + "</span> 开始坐庄！";
		Message msg = new Message("TXT_SYS", Integer.valueOf(0), str);
		Room room = (Room) this.roomStore.get(lottery.getRoomId());
		room.setMaster(maxMan);
		room.setMasterTimes(Integer.valueOf(1));
		MessageUtils.broadcast(room, msg);
		this.game02Service.returnMasterLoteryMoney(lottery, getMasterDeposit(room));

		sendNewGameRed(master, room);
	}

	private void sendNewGameRed(User master, Room room) throws GameException {
		Double deposit = Double.valueOf(getMasterDeposit(room));
		Double money = Double.valueOf(getConifg(room.getId(), "conf_money_game"));
		System.out.println("~~~~~~~~masterId:" + master.getId());
		if (this.lotteryService.moneyDown(master.getId(), deposit) == 0) {
			sendNewMasterRed(room);
			return;
		}
		Integer num = Integer.valueOf(getConifg(room.getId(), "conf_size"));
		Integer expired = Integer.valueOf(getConifg(room.getId(), "conf_expired"));
		BigDecimal bd = new BigDecimal(money.doubleValue());

		Lottery lottery = LotteryFactory.getDefaultBuilder(bd, num).setExpiredSeconds(expired).setType("2")
				.setSender(master.getId().intValue()).setDescription("恭喜发财,牛牛庄" + room.getMasterTimes()).setRoom(room)
				.build();
		GcLottery gcLottery = (GcLottery) BeanUtils.map(lottery, GcLottery.class);
		this.lotteryService.save(GcLottery.class, gcLottery);
		room.addLottery(lottery);

		lottery.open(master.getId().intValue());
		Message redMessage = new Message("RED", master.getId(), lottery);
		redMessage.setHeadImg(master.getHeadImg());
		MessageUtils.broadcast(room, redMessage);
	}

	private void sendNewMasterRed(Room room) throws GameException {
		BigDecimal bd = new BigDecimal(1);
		Integer number = Integer.valueOf(getConifg(room.getId(), "conf_size"));
		Integer expired = Integer.valueOf(getConifg(room.getId(), "conf_expired"));

		Lottery lottery = LotteryFactory.getDefaultBuilder(bd, number).setExpiredSeconds(expired).setType("2")
				.setSender(0).setDescription("开始抢庄,谁大谁庄!").setRoom(room).build();
		GcLottery gcLottery = (GcLottery) BeanUtils.map(lottery, GcLottery.class);
		this.lotteryService.save(GcLottery.class, gcLottery);
		room.addLottery(lottery);
		Message redMessage = new Message("RED", Integer.valueOf(0), lottery);
		redMessage.setHeadImg(User.SYSTEM_HEADIMG);
		redMessage.setNickName("系统");
		MessageUtils.broadcast(room, redMessage);
	}

	protected BigDecimal getInout(Room room, int nn) {
		Map<String, Object> map = room.getProperties();
		String key = "conf_n" + nn;
		Double types = Double.valueOf(1.0D);
		if (map.get(key) != null) {
			types = Double.valueOf(map.get(key).toString());
		}
		Double money = Double.valueOf(map.get("conf_money").toString());
		return new BigDecimal(money.doubleValue() * types.doubleValue());
	}

	protected double getDeposit(Room room) throws GameException {
		Double conf_money = Double.valueOf(getConifg(room.getId(), "conf_money"));
		Double conf_n10 = Double.valueOf(getConifg(room.getId(), "conf_n10"));
		return conf_money.doubleValue() * conf_n10.doubleValue();
	}

	protected double getMasterDeposit(Room room) throws GameException {
		Double conf_money = Double.valueOf(getConifg(room.getId(), "conf_money"));
		Double conf_n10 = Double.valueOf(getConifg(room.getId(), "conf_n10"));
		Integer num = Integer.valueOf(getConifg(room.getId(), "conf_size"));
		return conf_money.doubleValue() * conf_n10.doubleValue() * num.intValue();
	}
}
